/*
 * $Id$
 *
 * Copyright ( c ) 2014 XuNuo Corporation. All Rights Reserved.
 *
 * This software is the confidential and proprietary information of XuNuo
 * Corporation ("Confidential Information").  You shall not disclose such
 * Confidential Information and shall use it only in accordance with the terms
 * of the license agreement you entered into with XuNuo Corporation or a XuNuo
 * authorized reseller (the "License Agreement"). XuNuo may make changes to the
 * Confidential Information from time to time. Such Confidential Information may
 * contain errors.
 *
 * EXCEPT AS EXPLICITLY SET FORTH IN THE LICENSE AGREEMENT, XuNuo DISCLAIMS ALL
 * WARRANTIES, COVENANTS, REPRESENTATIONS, INDEMNITIES, AND GUARANTEES WITH
 * RESPECT TO SOFTWARE AND DOCUMENTATION, WHETHER EXPRESS OR IMPLIED, WRITTEN OR
 * ORAL, STATUTORY OR OTHERWISE INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A
 * PARTICULAR PURPOSE. XuNuo DOES NOT WARRANT THAT END USER'S USE OF THE
 * SOFTWARE WILL BE UNINTERRUPTED, ERROR FREE OR SECURE.
 *
 * XuNuo SHALL NOT BE LIABLE TO END USER, OR ANY OTHER PERSON, CORPORATION OR
 * ENTITY FOR INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL
 * DAMAGES, OR DAMAGES FOR LOSS OF PROFITS, REVENUE, DATA OR USE, WHETHER IN AN
 * ACTION IN CONTRACT, TORT OR OTHERWISE, EVEN IF XuNuo HAS BEEN ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES. XuNuo' TOTAL LIABILITY TO END USER SHALL NOT
 * EXCEED THE AMOUNTS PAID FOR THE XuNuo SOFTWARE BY END USER DURING THE PRIOR
 * TWELVE (12) MONTHS FROM THE DATE IN WHICH THE CLAIM AROSE.  BECAUSE SOME
 * STATES OR JURISDICTIONS DO NOT ALLOW LIMITATION OR EXCLUSION OF CONSEQUENTIAL
 * OR INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY NOT APPLY TO END USER.
 *
 * Copyright version 2.0
 */
package com.th.supcom.pds.phamapply.client.widget.phamapplydetail;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.carefx.fc.framework.web.gwt.util.FcUtils;

import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.form.CheckBox;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.th.supcom.pds.common.client.commom.PdsClientDateUtils;
import com.th.supcom.pds.common.client.model.CodeConstants;
import com.th.supcom.pds.common.enums.OrderRepetitionFlag;
import com.th.supcom.pds.common.utils.ClientUtils;
import com.th.supcom.pds.phamapply.client.model.InpPhamApplyDetailModel;
import com.th.supcom.pds.phamapply.client.model.InpPhamApplyDetailSummaryModel;
import com.th.supcom.pds.phamapply.client.model.InpPhamApplyPatInfoModel;
import com.th.supcom.pds.phamapply.client.service.InpPhamApplyDetailRpc;
import com.th.supcom.pds.phamapply.client.service.InpPhamApplyDetailRpcAsync;

/**
 * 药品请领Action
 * 
 * @author 杨冲
 */
public class PhamApplyAction
{
    private String m_applyBy;
    private String m_nurseUnit;
    private PhamApplyFields m_phamapplyFields;
    private PhamApplyDetailGrid m_applyDetailGrid;
    private PhamApplyCollectGrid m_applyCollectGrid;
    private PhamApplyOffsetGrid m_applyOffsetGrid;
    private PhamApplyCurrentApplyGrid m_applyCurrentApplyGrid;
    private PhamApplyPatientDispenseInfoGrid m_applyPatientDispenseInfoGrid;
    private static InpPhamApplyDetailRpcAsync s_applyDetailRpc = GWT.create (InpPhamApplyDetailRpc.class);

    /**
     * 设置药品请领文本组件
     * 
     * @param phamapplyFields
     */
    public void setphamapplyFields (PhamApplyFields phamapplyFields)
    {

        m_phamapplyFields = phamapplyFields;
    }

    public void setApplyDetailGrid (PhamApplyDetailGrid applyDetailGrid)
    {

        m_applyDetailGrid = applyDetailGrid;
    }

    public void setApplyCollectGrid (PhamApplyCollectGrid applyCollectGrid)
    {

        m_applyCollectGrid = applyCollectGrid;
    }

    public void setApplyPatientDispenseInfoGrid (PhamApplyPatientDispenseInfoGrid applyPatientDispenseInfoGrid)
    {

        m_applyPatientDispenseInfoGrid = applyPatientDispenseInfoGrid;
    }

    public void setApplyOffsetGrid (PhamApplyOffsetGrid applyOffsetGrid)
    {

        m_applyOffsetGrid = applyOffsetGrid;
    }

    public void setApplyCurrentApplyGrid (PhamApplyCurrentApplyGrid applyCurrentApplyGrid)
    {

        m_applyCurrentApplyGrid = applyCurrentApplyGrid;
    }

    /**
     * 构造函数
     */
    public PhamApplyAction ()
    {

    }

    /**
     * 初始化数据
     */
    public void initData ()
    {
        m_applyBy = ClientUtils.geteEmpModel ().getEmpCode ();
        m_nurseUnit = ClientUtils.getOrgModel ().getOrgCode ();

        initFiledsData ();
        getInpPatientInfoByNurseUnit ();
    }

    /**
     * 初始化组件数据
     */
    private void initFiledsData ()
    {
        m_phamapplyFields.getDispenseDays ().setValue (1);
        Date defaultDate = PdsClientDateUtils.getDateWithDayAdd (FcUtils.getCurrentServerDateTimeForClient (), (Integer) m_phamapplyFields.getDispenseDays ().getValue ());
        m_phamapplyFields.getDisepenseEndTime ().setValue (defaultDate);

        m_phamapplyFields.getLongBox ().setValue (true);
        m_phamapplyFields.getTempBox ().setValue (true);
    }

    /**
     * 获取长临标识
     */
    private String getRepetion ()
    {
        List <CheckBox> values = m_phamapplyFields.getRepetitionBoxGroup ().getValues ();
        // 如果长期和临时都没选中
        if (values.isEmpty ())
        {
            return OrderRepetitionFlag.None.getEnumCode ();
        }
        // 如果长期和临时都选中
        if (values.size () == 2)
        {
            return null;
        }
        // 如果只选中长期
        if (m_phamapplyFields.getLongBox ().getValue ())
        {
            return OrderRepetitionFlag.LongTime.getEnumCode ();
        }
        // 如果只选中临时
        if (m_phamapplyFields.getTempBox ().getValue ())
        {
            return OrderRepetitionFlag.Temp.getEnumCode ();
        }
        return null;
    }

    /**
     * 查询住院摆药明细
     */
    public void findPhamApplyDetailInfo ()
    {
        m_applyDetailGrid.getGrid ().mask ("正在加载中...");
        List <InpPhamApplyPatInfoModel> models = m_applyPatientDispenseInfoGrid.getSelectionModel ().getSelectedItems ();
        if (models.isEmpty ())
        {
            MessageBox.alert (CodeConstants.PROMPT, "没有选中患者！", null);
            m_applyDetailGrid.getGrid ().unmask ();
            clear ();
            return;
        }
        String repetition = getRepetion ();
        Date applyDate = FcUtils.getCurrentServerDateTimeForClient ();
        applyDate = PdsClientDateUtils.fillMinTimeOfDay (applyDate);
        Date endDate = m_phamapplyFields.getDisepenseEndTime ().getValue ();
        endDate = PdsClientDateUtils.fillMaxTimeOfDay (endDate);
        s_applyDetailRpc.findPhamApplyDetailInfo (models, m_nurseUnit, applyDate, endDate, m_applyBy, repetition, new AsyncCallback <List <InpPhamApplyDetailModel>> ()
        {

            @Override
            public void onFailure (Throwable caught)
            {
                MessageBox.alert (CodeConstants.PROMPT, caught.getLocalizedMessage (), null);
            }

            @Override
            public void onSuccess (List <InpPhamApplyDetailModel> result)
            {
                m_applyDetailGrid.getGroupingStore ().removeAll ();
                m_applyDetailGrid.getGroupingStore ().add (result);
                m_applyDetailGrid.getGrid ().unmask ();
                getPhamApplySummary ();
                getInpPatientInfoByNurseUnit ();
            }
        });
    }

    /**
     * 获取药品请领汇总
     */
    public void getPhamApplySummary ()
    {
        List <InpPhamApplyDetailModel> models = m_applyDetailGrid.getGrid ().getStore ().getModels ();
        List <InpPhamApplyDetailSummaryModel> summaryModels = new ArrayList <InpPhamApplyDetailSummaryModel> ();
        // 按照药品进行分组，计算每个药品的汇总
        Map <String, List <InpPhamApplyDetailModel>> phamMap = convertToMapByPhamCode (models);
        for (Map.Entry <String, List <InpPhamApplyDetailModel>> phamEntry : phamMap.entrySet ())
        {
            summaryModels.add (statPham (phamEntry.getValue ()));
        }
        m_applyCollectGrid.getGrid ().getStore ().removeAll ();
        m_applyCollectGrid.getGrid ().getStore ().add (summaryModels);
        getOffsetPhamSummary ();
    }

    /**
     * 根据药品标准码将list转换成Map
     * 
     * @return
     */
    private Map <String, List <InpPhamApplyDetailModel>> convertToMapByPhamCode (List <InpPhamApplyDetailModel> models)
    {
        Map <String, List <InpPhamApplyDetailModel>> map = new HashMap <String, List <InpPhamApplyDetailModel>> ();
        for (InpPhamApplyDetailModel InpPhamApplyDetailModel : models)
        {
            List <InpPhamApplyDetailModel> temp = null;

            if (map.containsKey (InpPhamApplyDetailModel.getPhamStdCode ()))
            {
                temp = map.get (InpPhamApplyDetailModel.getPhamStdCode ());
            }
            else
            {
                temp = new ArrayList <InpPhamApplyDetailModel> ();
            }
            temp.add (InpPhamApplyDetailModel);
            map.put (InpPhamApplyDetailModel.getPhamStdCode (), temp);
        }
        return map;
    }

    /**
     * 药品统计
     */
    private InpPhamApplyDetailSummaryModel statPham (List <InpPhamApplyDetailModel> list)
    {
        InpPhamApplyDetailSummaryModel summaryModel = new InpPhamApplyDetailSummaryModel ();

        int applyCountSum = 0;
        double costSum = 0.0;
        if (list.isEmpty ())
        {
            return summaryModel;
        }

        for (InpPhamApplyDetailModel model : list)
        {
            if (null == model.getApplyAmount () || null == model.getCosts ())
            {
                continue;
            }
            applyCountSum += model.getApplyAmount ();
            costSum += model.getCosts ();
        }
        InpPhamApplyDetailModel detailModel = list.get (0);

        summaryModel.setDetailSumAmount (applyCountSum);
        summaryModel.setPhamStdCode (detailModel.getPhamStdCode ());
        summaryModel.setNurseUnit (detailModel.getNurseUnit ());
        summaryModel.setDispensary (detailModel.getApplyDispensary ());
        summaryModel.setDispensaryName (detailModel.getApplyDispensaryName ());
        summaryModel.setApplySupplyFlag (detailModel.getApplySupplyFlag ());
        summaryModel.setStockEnoughFlag (detailModel.getStockEnoughFlag ());
        summaryModel.setPhamName (detailModel.getPhamName ());
        summaryModel.setPhamSpec (detailModel.getPhamSpec ());
        summaryModel.setTotalCost (costSum);
        summaryModel.setDosageUnit (detailModel.getApplyUnitName ());

        return summaryModel;
    }

    /**
     * 根据护理单元查患者信息
     */
    private void getInpPatientInfoByNurseUnit ()
    {
        s_applyDetailRpc.getInpPhamApplyPatInfos (m_nurseUnit, new AsyncCallback <List <InpPhamApplyPatInfoModel>> ()
        {

            @Override
            public void onSuccess (List <InpPhamApplyPatInfoModel> result)
            {
                m_applyPatientDispenseInfoGrid.getGrid ().getStore ().removeAll ();
                m_applyPatientDispenseInfoGrid.getGrid ().getStore ().add (result);
            }

            @Override
            public void onFailure (Throwable caught)
            {
                MessageBox.alert (CodeConstants.PROMPT, caught.getLocalizedMessage (), null);
            }
        });
    }

    /**
     * 保存住院患者药品请领信息
     */
    public void savePhamApplyDetail ()
    {
        List <InpPhamApplyDetailModel> models = m_applyDetailGrid.getGrid ().getStore ().getModels ();
        if (models.isEmpty ())
        {
            MessageBox.alert (CodeConstants.PROMPT, "没有请领信息保存！", null);
            return;
        }

        final MessageBox box = MessageBox.wait ("请领进度", "正在请领请稍等", "请领中...");
        Date applyDate = FcUtils.getCurrentServerDateTimeForClient ();
        Date endDate = m_phamapplyFields.getDisepenseEndTime ().getValue ();
        endDate = PdsClientDateUtils.fillMaxTimeOfDay (endDate);
        s_applyDetailRpc.saveInpPhamApplyDetailList (models, m_nurseUnit, applyDate, endDate, m_applyBy, new AsyncCallback <Void> ()
        {

            @Override
            public void onFailure (Throwable caught)
            {
                box.close ();
                MessageBox.alert (CodeConstants.PROMPT, caught.getLocalizedMessage (), null);
            }

            @Override
            public void onSuccess (Void result)
            {
                MessageBox.alert (CodeConstants.PROMPT, "请领成功", null);
                clear ();
                getInpPatientInfoByNurseUnit ();
                box.close ();
            }
        });
    }

    /**
     * 清屏
     */
    public void clear ()
    {
        m_applyDetailGrid.getGrid ().getStore ().removeAll ();
        m_applyCollectGrid.getGrid ().getStore ().removeAll ();
        m_applyOffsetGrid.getGrid ().getStore ().removeAll ();
        m_applyCurrentApplyGrid.getGrid ().getStore ().removeAll ();
    }

    /**
     * 获取可冲抵的药品信息
     */
    public void getOffsetPhamSummary ()
    {
        List <InpPhamApplyDetailSummaryModel> models = m_applyCollectGrid.getGrid ().getStore ().getModels ();
        if (models.isEmpty ())
        {
            return;
        }

        s_applyDetailRpc.getOffsetPhamSummaryList (models, new AsyncCallback <List <InpPhamApplyDetailModel>> ()
        {

            @Override
            public void onFailure (Throwable caught)
            {
                MessageBox.alert (CodeConstants.PROMPT, caught.getLocalizedMessage (), null);
            }

            @Override
            public void onSuccess (List <InpPhamApplyDetailModel> result)
            {
                addOffsetAjdustData (result, m_applyCollectGrid.getGrid ().getStore ().getModels ());
            }
        });
    }

    /**
     * 将本次请领药品数据和可冲抵的药品信息进行对照后填入Grid中
     */
    private void addOffsetAjdustData (List <InpPhamApplyDetailModel> applyPhams, List <InpPhamApplyDetailSummaryModel> applySummarys)
    {
        ArrayList <InpPhamApplyDetailSummaryModel> models = new ArrayList <InpPhamApplyDetailSummaryModel> ();
        Map <String, InpPhamApplyDetailSummaryModel> map = convertSummaryListToMap (applySummarys);
        for (InpPhamApplyDetailModel model : applyPhams)
        {
            if (map.containsKey (model.getPhamStdCode ()))
            {
                models.add (map.get (model.getPhamStdCode ()));
            }
        }

        m_applyCurrentApplyGrid.getGrid ().getStore ().removeAll ();
        m_applyCurrentApplyGrid.getGrid ().getStore ().add (models);
        m_applyOffsetGrid.getGrid ().getStore ().removeAll ();
        m_applyOffsetGrid.getGrid ().getStore ().add (applyPhams);
    }

    /**
     * 将汇总列表转换成map
     * 
     * @param applySummarys
     * @return
     */
    private Map <String, InpPhamApplyDetailSummaryModel> convertSummaryListToMap (List <InpPhamApplyDetailSummaryModel> applySummarys)
    {
        Map <String, InpPhamApplyDetailSummaryModel> map = new HashMap <String, InpPhamApplyDetailSummaryModel> ();
        for (InpPhamApplyDetailSummaryModel model : applySummarys)
        {
            map.put (model.getPhamStdCode (), model);
        }
        return map;
    }
}
